package org.flowable.pz.controller;

import org.flowable.pz.entity.dto.FlowableProcessDto;
import org.flowable.pz.entity.dto.FlowablePageDto;
import org.flowable.pz.entity.dto.FlowableTaskDto;
import org.flowable.pz.entity.vo.FlowableProcessVo;
import org.flowable.pz.entity.dto.FlowableResultDto;
import org.flowable.pz.entity.vo.FlowableProcessQueryVo;
import org.flowable.pz.entity.vo.FlowableTaskQueryVo;
import org.flowable.pz.entity.vo.FlowableTaskVo;
import org.flowable.pz.exception.FlowableCustomException;
import org.flowable.pz.service.FlowableProcess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/flowable")
public class FlowableProcessController {

    @Autowired
    private FlowableProcess flowableProcess;

    /**
     * 启动流程
     * */
    @PostMapping("/process/start")
    public FlowableResultDto<String> processStart(@RequestBody FlowableProcessVo instanceVo){
        return FlowableResultDto.success( flowableProcess.startProcess(instanceVo.getProcessDefineKey(), instanceVo.getVariable()) );
    }

    /**
     * 取消流程
     * */
    @PostMapping("/process/cancel")
    public FlowableResultDto<Void> processCancel(@RequestParam(value = "processInstanceId") String processInstanceId,
                                                 @RequestParam(value = "comment", required = false) String comment){
        flowableProcess.cancelProcess(processInstanceId, comment);
        return FlowableResultDto.success();
    }

    /**
     * 终止流程
     * */
    @PostMapping("/process/stop")
    public FlowableResultDto<Void> processStop(@RequestParam(value = "processInstanceId") String processInstanceId,
                                               @RequestParam(value = "comment", required = false) String comment){
        flowableProcess.stopProcess(processInstanceId, comment);
        return FlowableResultDto.success();
    }

    /**
     * 挂起流程
     * */
    @PostMapping("/process/suspend")
    public FlowableResultDto<Void> processSuspend(@RequestParam(value = "processInstanceId") String processInstanceId){
        flowableProcess.suspendProcess(processInstanceId);
        return FlowableResultDto.success();
    }

    /**
     * 流程实例列表
     * */
    @GetMapping("/process/list")
    public FlowableResultDto<FlowablePageDto<FlowableProcessDto>> processList(@RequestParam(value = "processDefineKey", required = false) String processDefineKey,
                                                                              @RequestParam(value = "processInstanceId", required = false) String processInstanceId,
                                                                              @RequestParam(value = "status", required = false) Integer status,
                                                                              @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
                                                                              @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize){
        return FlowableResultDto.success(flowableProcess.processList(new FlowableProcessQueryVo(processDefineKey, processInstanceId, status, pageIndex, pageSize)));
    }

    /**
     * 我发起的
     * */
    @GetMapping("/myProcess/list")
    public FlowableResultDto<FlowablePageDto<FlowableProcessDto>> myProcessList(@RequestParam(value = "processDefineKey", required = false) String processDefineKey,
                                                                                @RequestParam(value = "processInstanceId", required = false) String processInstanceId,
                                                                                @RequestParam(value = "status", required = false) Integer status,
                                                                                @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
                                                                                @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize){
        return FlowableResultDto.success(flowableProcess.myProcessList(new FlowableProcessQueryVo(processDefineKey, processInstanceId, status, pageIndex, pageSize)));
    }

    /**
     * 任务列表  待审批
     * */
    @GetMapping("/task/todo")
    public FlowableResultDto<FlowablePageDto<FlowableTaskDto>> todoTaskList(@RequestParam(value = "processDefineKey", required = false) String processDefineKey,
                                                                 @RequestParam(value = "processInstanceId", required = false) String processInstanceId,
                                                                 @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
                                                                 @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize){
        return FlowableResultDto.success(flowableProcess.todoTaskList(new FlowableTaskQueryVo(processDefineKey, processInstanceId, pageIndex, pageSize)));
    }

    /**
     * 任务列表 已审批
     * */
    @GetMapping("/task/approved")
    public FlowableResultDto<FlowablePageDto<FlowableTaskDto>> approvedTaskList(@RequestParam(value = "processDefineKey", required = false) String processDefineKey,
                                                                                @RequestParam(value = "processInstanceId", required = false) String processInstanceId,
                                                                                @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
                                                                                @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize){
        return FlowableResultDto.success(flowableProcess.approvedTaskList(new FlowableTaskQueryVo(processDefineKey, processInstanceId, pageIndex, pageSize)));
    }

    /**
     * 任务审批
     * */
    @PostMapping("/task/complete")
    public FlowableResultDto<Void> completeProcess(@RequestBody FlowableTaskVo flowableTaskVo){
        flowableProcess.completeProcess(flowableTaskVo.getTaskId(), flowableTaskVo.getComment(), flowableTaskVo.getVariable());
        return FlowableResultDto.success();
    }

    /**
     * 流程变量
     * */
    @GetMapping("/process/variables/{processId}")
    public FlowableResultDto<Map<String,Object>> processVariables(@PathVariable(value = "processId") String processId){
        return FlowableResultDto.success(flowableProcess.variables(processId));
    }

    /**
     * 流转记录
     * */
    @GetMapping("/process/records/{processId}")
    public FlowableResultDto<List<FlowableTaskDto>> processRecords(@PathVariable(value = "processId") String processId){
        return FlowableResultDto.success(flowableProcess.records(processId));
    }

    /**
     * 流程图
     * */
    @GetMapping("/process/diagram/{processId}")
    public void getProcessDiagram(@PathVariable String processId,
                                  HttpServletResponse response){
        try {
            byte[] diagram = flowableProcess.processDiagram(processId);

            response.setContentType("image/png");
            response.setHeader("Content-Disposition","inline; filename=\"process-diagram.png\"");

            OutputStream out = response.getOutputStream();
            out.write(diagram);
            out.flush();
        } catch (Exception e) {
            throw new FlowableCustomException(e.getMessage());
        }
    }
}
